﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Threading;
using Microsoft.Win32;
using System.Security.Cryptography;
using System.Windows.Forms;


namespace MixSNS
{
    public class ParameterComparer : IComparer<APIParameter>
    {
        public int Compare(APIParameter x, APIParameter y)
        {
            if (x.Name == y.Name)
            {
                return string.Compare(x.Value, y.Value);
            }
            else
            {
                return string.Compare(x.Name, y.Name);
            }
        }
    }

    public class APIParameter
    {
        private string name = null;
        private string value = null;

        public APIParameter(string name, string value)
        {
            this.name = name;
            this.value = value;
        }

        public string Name
        {
            get { return name; }
        }

        public string Value
        {
            get { return value; }
        }
    }

    class MixSNSSupport
    {
        #region define var
        public const string APP_KEY = "09e7b9c922de418b935c06ea8a536d8a";
        public const string SECRET_KEY  = "2ad7c60221d048b59403e0581b434419";
        public const string ACCESS_TOKEN = "\"access_token\":\"";
        public const string SESSION_KEY = "\"session_key\":\"";
        public const string SESSION_KEY_END = "\"},\"oauth_token";
        public const string RENREN_SERVER = "http://api.renren.com/restserver.do";
        public const string EXPIRES_IN = "expires_in=";
        public const string CODE = "code=";
        public const string SERCET_KEY = "2ad7c60221d048b59403e0581b434419";
        public const string CALL_BACK_URL = "about:blank";
        public const string SESSION_KEY_URL = "https://graph.renren.com/renren_api/session_key";
        public const string ACCESS_TOKEN_URL = "https://graph.renren.com/oauth/token";
        public const string SCOPE_VAR = "scope=status_update,publish_checkin";
        public const string MIXSNS_COPY_RIGHT = "----set by MixSNS 0.1"; 
        public static string access_token = null;
        public static string expires_in = null;
        public static string session_key = null;
        public static string code = null;
        #endregion

        #region getSig 
        public static string getSig(List<APIParameter> APIs)
        {
            APIs.Sort(new ParameterComparer());
            StringBuilder sbList = new StringBuilder();
            foreach (APIParameter API in APIs)
            {
                sbList.AppendFormat("{0}={1}", API.Name, API.Value);
            }
            sbList.Append(SERCET_KEY);

            MD5 md5Hash = MD5.Create();
            byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(sbList.ToString()));
            sbList = new StringBuilder();
            foreach (byte d in data)
            {
                sbList.Append(d.ToString("x2"));
            }
            return sbList.ToString();
        }
        #endregion

        #region http post

        public static string httpPost(string url, string postPara)
        {
            HttpWebRequest myHttpWebRequest = WebRequest.Create(url) as HttpWebRequest;
            StreamWriter requestWriter = null;
            StreamReader responseReader = null;
            string responseData = null;
            myHttpWebRequest.Method = "POST";
            myHttpWebRequest.ContentType = "application/x-www-form-urlencoded";
            myHttpWebRequest.ServicePoint.Expect100Continue = false;
            myHttpWebRequest.Timeout = 20000;
            Stream responseStream = null;
            try
            {
                requestWriter = new StreamWriter(myHttpWebRequest.GetRequestStream());
                requestWriter.Write(postPara);
                requestWriter.Close();
                requestWriter = null;
                responseStream = myHttpWebRequest.GetResponse().GetResponseStream();
                responseReader = new StreamReader(responseStream);
                responseData = responseReader.ReadToEnd();
            }
            catch
            {
                throw;
            }
            finally
            {
                if (requestWriter != null)
                {
                    requestWriter.Close();
                    requestWriter = null;
                }

                if (responseStream != null)
                {
                    responseStream.Close();
                    responseStream = null;
                }

                if (responseReader != null)
                {
                    responseReader.Close();
                    responseReader = null;
                }
            }
            return responseData;
        }
        #endregion

        #region get string from paras

        public static string getStringFromParas(List<APIParameter> paras)
        {
            if (paras == null || paras.Count == 0)
                return "";
            StringBuilder sbList = new StringBuilder();
            int count = 1;
            foreach (APIParameter para in paras)
            {
                sbList.AppendFormat("{0}={1}", para.Name, para.Value);
                if (count < paras.Count)
                    sbList.Append("&");
                count++;
            }
            return sbList.ToString(); ;
        }

        #endregion

        #region get session key
        public static bool getSessionKey()
        {
            if (access_token == null)
                return false;
            string url = SESSION_KEY_URL;
            url += "?oauth_token=";
            url += access_token;
            string jasonContent = httpPost(url, "");

            int sessionKeyPosition = jasonContent.IndexOf(SESSION_KEY);
            int endSessionKeyPosition = jasonContent.IndexOf(SESSION_KEY_END);

            session_key = jasonContent.Substring(sessionKeyPosition + SESSION_KEY.Length, endSessionKeyPosition - sessionKeyPosition - SESSION_KEY.Length);
            MessageBox.Show(jasonContent);
            MessageBox.Show(session_key);
            return true;
        }
        #endregion

        #region get access token by code
        public static bool getAccessToken()
        {
            if (code == null)
                return false;
            string url = ACCESS_TOKEN_URL;
            url += "?grant_type=authorization_code&";
            url += "code=" + code + "&";
            url += "client_id="+APP_KEY+"&";
            url += "client_secret="+SECRET_KEY+"&";
            url += "redirect_uri=http://graph.renren.com/oauth/login_success.html";
            string jasonContent = httpPost(url, "");
            MessageBox.Show(jasonContent);
            int access_tokenPosition = jasonContent.IndexOf(ACCESS_TOKEN);
            if (access_tokenPosition != -1)
            {
                MixSNSSupport.access_token = jasonContent.Substring(access_tokenPosition + ACCESS_TOKEN.Length, jasonContent.Length - access_tokenPosition - ACCESS_TOKEN.Length-2);
                MessageBox.Show(MixSNSSupport.access_token);
                getSessionKey();
            }
            else
            {
                MessageBox.Show("ERROR");
            }
           
            return true;
        }
        #endregion

        #region update statues 
        public static bool updateStatue(string statue,string placeID)
        {
            if (session_key == null)
                return false;
            string status = statue;// +MixSNSSupport.MIXSNS_COPY_RIGHT;

            List<APIParameter> paras = new List<APIParameter>();
            paras.Add(new APIParameter("api_key", MixSNSSupport.APP_KEY));
            paras.Add(new APIParameter("method", "status.set"));
            paras.Add(new APIParameter("v", "1.0"));
            paras.Add(new APIParameter("status", status));
            paras.Add(new APIParameter("session_key", MixSNSSupport.session_key));
            if (placeID != "")
                paras.Add(new APIParameter("place_id",placeID));
            paras.Add(new APIParameter("sig", MixSNSSupport.getSig(paras)));
            string responseData = MixSNSSupport.httpPost(MixSNSSupport.RENREN_SERVER, MixSNSSupport.getStringFromParas(paras));
            System.Xml.XmlDocument myResponData = new System.Xml.XmlDocument();
            myResponData.LoadXml(responseData);
            return true;
        }
        #endregion

        #region get place id
        public static string getPlaceID(string poi_id, string name, string address, string longitude, string latitude)
        {
            if (access_token == null)
                return null;
            string placeID = "";
            List<APIParameter> paras = new List<APIParameter>();
            paras.Add(new APIParameter("method", "places.create"));
            paras.Add(new APIParameter("access_token", access_token));
            paras.Add(new APIParameter("v", "1.0"));
            paras.Add(new APIParameter ("poi_id",poi_id));
            paras.Add(new APIParameter("name", name));
            paras.Add(new APIParameter("address", address));
            paras.Add(new APIParameter("longitude", longitude));
            paras.Add(new APIParameter("latitude", latitude));
            paras.Add(new APIParameter("sig", MixSNSSupport.getSig(paras)));
            string responseData = MixSNSSupport.httpPost(MixSNSSupport.RENREN_SERVER, MixSNSSupport.getStringFromParas(paras));
            System.Xml.XmlDocument myResponseData = new System.Xml.XmlDocument();
            myResponseData.LoadXml(responseData);
            MessageBox.Show(responseData);
            return placeID;
        }
        #endregion
    }
}

